/*
 * @lc app=leetcode.cn id=36 lang=golang
 * @lcpr version=30118
 *
 * [36] 有效的数独
 */

// @lcpr-template-start

// @lcpr-template-end
// @lc code=start
func isValidSudoku(board [][]byte) bool {
	for row := 0; row < 9; row++ {
		if !isValidRow(board, row) {
			return false
		}
	}

	for column := 0; column < 9; column++ {
		if !isValidColumn(board, column) {
			return false
		}
	}

	for box := 0; box < 9; box++ {
		if !isValidBox(board, box) {
			return false
		}
	}

	return true
}

func isValidRow(board [][]byte, row int) bool {
	visited := make(map[byte]bool)
	for i := 0; i < 9; i++ {
		if board[row][i] == '.' {
			continue
		}
		if _, ok := visited[board[row][i]]; ok {
			return false
		}
		visited[board[row][i]] = true
	}
	return true
}

func isValidColumn(board [][]byte, column int) bool {
	visited := make(map[byte]bool)
	for i := 0; i < 9; i++ {
		if board[i][column] == '.' {
			continue
		}
		if _, ok := visited[board[i][column]]; ok {
			return false
		}
		visited[board[i][column]] = true
	}
	return true
}

func isValidBox(board [][]byte, box int) bool {
	visited := make(map[byte]bool)

	row, column := box/3*3, (box%3)*3

	for i := row; i < row+3; i++ {
		for j := column; j < column+3; j++ {
			if board[i][j] == '.' {
				continue
			}
			if _, ok := visited[board[i][j]]; ok {
				return false
			}
			visited[board[i][j]] = true
		}
	}
	return true
}

// @lc code=end

/*
// @lcpr case=start
// [["5","3",".",".","7",".",".",".","."],["6",".",".","1","9","5",".",".","."],[".","9","8",".",".",".",".","6","."],["8",".",".",".","6",".",".",".","3"],["4",".",".","8",".","3",".",".","1"],["7",".",".",".","2",".",".",".","6"],[".","6",".",".",".",".","2","8","."],[".",".",".","4","1","9",".",".","5"],[".",".",".",".","8",".",".","7","9"]]\n
// @lcpr case=end

// @lcpr case=start
// [["8","3",".",".","7",".",".",".","."],["6",".",".","1","9","5",".",".","."],[".","9","8",".",".",".",".","6","."],["8",".",".",".","6",".",".",".","3"],["4",".",".","8",".","3",".",".","1"],["7",".",".",".","2",".",".",".","6"],[".","6",".",".",".",".","2","8","."],[".",".",".","4","1","9",".",".","5"],[".",".",".",".","8",".",".","7","9"]]\n
// @lcpr case=end

*/

